#pragma once

#include <cstddef>
#include <functional>
#include<iostream>
#include<memory>
#include<sys/wait.h>
#include "InetAddr.hpp"
#include "Log.hpp"
#include"Socket.hpp" 

namespace TcpServerModule
{
    using namespace SocketModule;
    using namespace LogModule;

    using tcphandler_t = std::function<bool(SockPtr,InetAddr)>;
    //只负责流式IO读写
    class TcpServer
    {
    public:
    //创建Tcp套接字，通过基类指向子类，使用子类提供的方法
        TcpServer(int port)
        :_listensockp(std::make_unique<TcpSocket>())
        ,_port(port)
        ,_running(false)
        {}

        //初始化服务器
        void InitServer(tcphandler_t handler)
        {
            _handler = handler;
            _listensockp->BuildTcpSocketMethod(_port);

        }

        //服务器进入循环开始工作
        void Loop()
        {
            _running = true;
            while(_running)
            {
                //1.accept
                InetAddr cilentaddr;
                auto sockfd = _listensockp->Accepter(&cilentaddr);
                if(sockfd == nullptr) continue;
                LOG(LogLevel::DEBUG) << "get a new client, info is: " << cilentaddr.Addr();
                //2.IO处理
                // sockfd->Recv(out);
                // sockfd->Send(in);
                pid_t id = fork();
                if(id == 0)
                {
                    _listensockp->Close();
                    if(fork() > 0) exit(0);
                    _handler(sockfd,cilentaddr);
                    exit(0);
                }
                sockfd->Close();
                waitpid(id,nullptr,0);
            }
            _running = false;
        }

        ~TcpServer()
        {
            _listensockp->Close();
        }
    private:
        //tcp服务器一定要有自己的listensockfd
        std::unique_ptr<Socket> _listensockp;
        //服务器运行状态
        bool _running;
        //处理方法
        tcphandler_t _handler;
        //端口号
        int _port;
    };
};